/**
 *       Copyright (c) 2011 Lukas Zaruba
 * 
 *   This file is part of ParPortTester
 *
 *   ParPortTester is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Lesser General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   ParPortTester is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Lesser General Public License for more details.
 *
 *   You should have received a copy of the GNU Lesser General Public License
 *   along with ParPortTester. If not, see <http://www.gnu.org/licenses/>.
 */


package net.zarubsys.parporttester.io;

import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * @author  &lt;A HREF=&quot;mailto:lukas.zaruba@gmail.com&quot;&gt;Lukas Zaruba&lt;/A&gt; zarubsys.net
 */
public class ParallelPortAccessor {
	
	private static final String LIBRARY_NAME = "parportaccessor";
	
	private static final Logger LOG = Logger.getLogger(ParallelPortAccessor.class.getName());
	
	private int address;
	private boolean opened;
	
	public void closeLptPort() throws IllegalStateException {
		if (!opened) {
			LOG.info("Trying to close port \"" + address + "\" which is not opened...");
                return;
        }
        int i = closePort(address);
        if (i != 0) throw new IllegalStateException("Error closing port \"" + address + "\" , error code " + i);
        opened = false;
        LOG.info("Port address \"" + address + "\" closed...");
	}

	public void openLptPort(int address) throws IllegalStateException {
        this.address = address;
        if (opened) throw new IllegalStateException("Port is already opened!!!");
        int i = openPort(address);
        if (i != 0) throw new IllegalStateException("Error opening port \"" + address + "\" , error code " + i);
        opened = true;
        LOG.info("Port address \"" + address + "\" opened...");
	}
	
	public int readOneByte(int address) {
		if (!opened) throw new IllegalStateException("Port \"" + address + "\" is not opened!!!");
		int i = readByte(address);
		return i;
	}
	
	public void writeOneByte(int address, int value) {
		if (!opened) throw new IllegalStateException("Port \"" + address + "\" is not opened!!!");
        int i = writeByte(address, value);
        if (i != 0) throw new RuntimeException("Error while writing byte " + value + " to address " + address + ". Error code " + i + "!");
	}
	
	/**
	 * Intended to be used for closing ports on exit
	 * (doesn't throw exception when no port is open)
	 * For normal usage see {@link #closeLptPort()}
	 */
	public void closeOpenedPort() {
		if (opened) {
			LOG.info("There was open port on address " + address + ". Going to close it...");
			closeLptPort();
		}
	}
	
//	private static int closePort(int address) {
//		return 0;
//	}
//	private static int openPort(int address) {
//		return 0;
//	}
//	private static int readByte(int address) {
//		return 12;
//	}
//	private static int writeByte(int address, int value) {
//		System.out.println(value + " -> " + address);
//		return 0;
//	}
	
	private static native int closePort(int address);
	private static native int openPort(int address);
	private static native int readByte(int address);
	private static native int writeByte(int address, int value);
	
	static {
        LOG.info("Loading shared library \"" + LIBRARY_NAME + "\"");
        try {
        	System.loadLibrary(LIBRARY_NAME);
        } catch (UnsatisfiedLinkError e) {
        	LOG.log(Level.SEVERE, "Loading shared library \"" + LIBRARY_NAME + "\" failed.", e);
        }
    }

}
